package com.zjsru.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;

import com.zjsru.clients.ProductClient;
import com.zjsru.clients.UserClient;
import com.zjsru.pojo.Order;
import com.zjsru.pojo.Result;
import com.zjsru.pojo.User;
import com.zjsru.service.OrderService;
import com.zjsru.utils.RedisData;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;


/*@Controller
@ResponseBody*/
@RestController
public class OrderController {
    @Value("${ExpireTime}")
    private Integer expireTime;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    OrderService orderService;
    @Qualifier("com.zjsru.clients.ProductClient")
    @Autowired
    ProductClient productClient;

    //从redis中查询订单信息
    public Order queryWithLogicalExpire(Long orderId){
        String key = "order:info:" + orderId;
        //1.从redis查询缓存
        String json = stringRedisTemplate.opsForValue().get(key);
        //4.命中，先把json反序列化为对象
        RedisData redisData = JSONUtil.toBean(json, RedisData.class);
        JSONObject data = (JSONObject) redisData.getData();
        return JSONUtil.toBean(data, Order.class);
    }

    //将订单信息写入redis中，并加上逻辑过期时间
    public void saveOrder2Redis(Order order){
        //封装逻辑过期时间
        RedisData redisData = new RedisData();
        redisData.setData(order);
        //设置逻辑过期时间
        redisData.setExpireTime(LocalDateTime.now().plusSeconds(expireTime));
        //保存数据到redis中
        stringRedisTemplate.opsForValue().set("order:info:" + order.getOrder_Id(), JSON.toJSONString(redisData));
    }

    //根据orderId查询订单
    @GetMapping("/order/query/{order_Id}")
    public Result queryOrderByOrderId(@PathVariable("order_Id") Long order_Id) {
        try {
            //从redis里查询
            Order order = queryWithLogicalExpire(order_Id);
            if (order == null) {
                Order order1 = orderService.queryOrderById(order_Id);
                if (order1 == null) {
                    return Result.error(500, "订单不存在");
                }
                saveOrder2Redis(order1);
                return Result.success(order1);
            }
            return Result.success(order);
        } catch (RuntimeException e) {
            return Result.error(500, e.getMessage());
        }
    }
    //根据userId查询订单
    @GetMapping("/order/query/user/{user_Id}")
    public Result queryOrderByUserId(@PathVariable("user_Id") Long user_Id) {
        //查询订单
        List<Order> orderList = orderService.queryOrderByUserId(user_Id);
        if (orderList == null) {
            return Result.error(500, "查询订单为空");
        }
//        for (Order order : orderList){
//            queryWithLogicalExpire(order.getOrder_Id());
//        }
        return Result.success(orderList);
    }
    //创建订单
    //事务
    @Transactional
    @PostMapping("/order/create")
    public Result createOrder(@RequestBody Order order) {
        try{
            Order order1 = orderService.createOrder(order);
            //将订单信息存储到redis中，设置逻辑过期时间
            saveOrder2Redis(order1);
            return Result.success("创建成功！订单号为：" + order1.getOrder_Id());
        } catch (RuntimeException e) {
            return Result.error(500, e.getMessage());
        }
    }

    //删除订单
    public void deleteOrder(Long order_Id){
        orderService.deleteOrder(order_Id);
        //删除redis中的订单信息
        stringRedisTemplate.delete("order:info" + order_Id);
    }

    //订单状态更改为已支付
    @PutMapping("/order/{order_Id}/pay")
    public Result updateOrderStatus(@PathVariable("order_Id") Long order_Id) {
        try{
            Order order = orderService.queryOrderById(order_Id);
            if (Objects.equals(order.getStatus(), "已支付")){
                return Result.error(500, "订单已支付");
            }
            orderService.updateOrderStatus(order_Id);
            //更新redis中的订单信息
            saveOrder2Redis(queryWithLogicalExpire(order_Id));
            return Result.success("订单状态更新成功！");
        } catch (RuntimeException e) {
            return Result.error(500, e.getMessage());
        }
    }

    //每十分钟扫描未支付订单且超时5分钟订单
    @Scheduled(cron = "0 0/10 * * * ?")
    public void checkOrderStatus(){
        System.out.println("开始检查订单状态");
        String key = "order:info";
        String status = "未支付";
        //获取当前时间
        LocalDateTime now = LocalDateTime.now();
        //1.获取所有未支付订单
        List<Order> orderList = orderService.queryOrderByStatus(status);
        //2.遍历所有未支付订单
        for (Order order : orderList) {
            //2.1从redis中获取数据
            String orderJson = stringRedisTemplate.opsForValue().get(key + ":" + order.getOrder_Id());
            if (StrUtil.isNotBlank(orderJson)) {
                RedisData redisData = JSONUtil.toBean(orderJson, RedisData.class);
                JSONObject data = (JSONObject) redisData.getData();
                Order order1 = JSONUtil.toBean(data, Order.class);
                LocalDateTime expireTime = redisData.getExpireTime();
                //2.2获取逻辑过期时间加上5分钟的时间
                LocalDateTime expireTimePlus = expireTime.plusMinutes(5);
                //2.3判断逻辑过期时间是否超过5分钟
                if (expireTimePlus.isBefore(now)) {
                    //调用回复库存接口
                    productClient.updateProductCount(order1.getNum(), order1.getProduct_Id());
                    //调用删除订单接口
                    deleteOrder(order1.getOrder_Id());
                }
            }
        }
    }
}
